package cn.sciento.farm.devicemanager.fjhsxq.utils;

import cn.sciento.farm.devicemanager.fjhsxq.model.common.BaseReq;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.text.StringEscapeUtils;

import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 加密demo
 * @author wucy
 **/
public class EncrypUtils {


    /**
     * 获取当前的时间戳
     * @return yyyyMMddHHmmss
     */
    public static String getTimestamp(){
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String result=dateFormat.format(date);
        return result;
    }

    /**
     * 获取六位随机数
     * @return 123456
     */
    public static String getSixDigitsRandom() {
        Random random = new Random();
        String result = "";
        for (int i = 0; i < 5; i++) {
            result += random.nextInt(10);

        }
        return result;
    }

    /**
     * MD5加密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public static byte[] encryptMD5(String data) throws Exception {
        System.out.println("待加密的数据："+data);
        //转成GBK编码
        byte[] btInput = data.getBytes("GBK");
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(btInput);
        return md5.digest();
    }

    /**
     * byte中的大写字母转小写
     * @param data
     * @return
     * @throws Exception
     */
    public static byte[] toLowerCase(byte[] data) throws Exception {
        //转成GBK编码
       for(byte b: data){
           if (b >= 65 && b <= 90){
               b += 32;
           }
       }
        return data;
    }


    /**
     * 判断字符串长度是否过长
     * @param str
     * @param length
     * @return
     */
    public static boolean judgeStrLength(String str,int length){
        try {
            int len=str.getBytes("UTF-8").length;
            if(len>length){
                return false;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return true;
    }



    /**
     * 根据请求参数名排序
     * @return
     */
    public static String sortFieldName(BaseReq req, String encrypKey){
        List<String> keyStrList=new ArrayList<>();
        keyStrList.add("appId");
        keyStrList.add("content");
        keyStrList.add("nonce");
        keyStrList.add("requestSeq");
        keyStrList.add("requestTime");
        Collections.sort(keyStrList);   //对字段名进行排序


        //按照字段名的 ASCII 码 从小到大排序（字典序）后，使用 URL 键值对的格式（即 key1=value1&key2=value2…）拼接成字符串
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<keyStrList.size();i++){
            if(i!=0){
                sb.append("&");
            }
            if(keyStrList.get(i).equals("appId")){
                sb.append("appId="+req.getHeader().getAppId());
            }
            if(keyStrList.get(i).equals("content")){
                //为保证content的数据一致，需先将实体或者json字符串转换成JSONObject类型，再根据JSONObject获取content的内容
                String json= JSONObject.toJSONString(req);
                JSONObject object= JSON.parseObject(json);
                String content= StringEscapeUtils.unescapeJava(object.getString("content"));
                if (json.startsWith("\"")) {
                    content = EncrypUtils.replaceFirst(content, "\"", "");
                }
                if (json.endsWith("\"")) {
                    content = EncrypUtils.replaceLast(content, "\"", "");
                }
                sb.append("content="+content.trim());
            }
            if(keyStrList.get(i).equals("nonce")){
                sb.append("nonce="+req.getHeader().getNonce());
            }
            if(keyStrList.get(i).equals("requestSeq")){
                sb.append("requestSeq="+req.getHeader().getRequestSeq());
            }
            if(keyStrList.get(i).equals("requestTime")){
                sb.append("requestTime="+req.getHeader().getRequestTime());
            }
        }
        //拼接上key
        sb.append("&"+encrypKey);
        // System.out.println("拼接完的报文"+String.valueOf(sb));
        return String.valueOf(sb);
    }

    public static String replaceFirst(String ret, String strToReplace, String replaceWithThis) {

        return ret.replaceFirst(strToReplace, replaceWithThis);
    }

    public static String replaceLast(String text, String strToReplace, String replaceWithThis) {
        //
        return text.replaceFirst("(?s)" + strToReplace + "(?!.*?" + strToReplace + ")", replaceWithThis);
    }


    /**
     * 获取加密完成后的消息签名
     * @param req
     * @return 消息签名
     */
    public static String getMsgSignature(BaseReq req,String encrypKey){
        String result="";
        try {
            String sortStr= sortFieldName(req,encrypKey);//在设定好的字段顺序拼接字段
            // System.out.println("排序好后的字符串: "+sortStr );

            String md5Srt = MD5.sign(sortStr,"utf-8");//使用MessageDigest的MD5方法加密格式为GBK
            // System.out.println("md5加密后的字符串: "+md5Srt );

            String lowerStr=md5Srt.toLowerCase();//将大写字母转化为小写
            // System.out.println("小写转换后的字符串: "+md5Srt );

            result=MD5.encryptBASE64(lowerStr.getBytes());//转成Base64编码
            // System.out.println("计算后的消息签名: "+result );
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

}
